import axios, { AxiosResponse } from 'axios';
import { message } from 'tea-component/lib/message/Message';
import { NavigateFunction } from 'react-router-dom';
import ReconnectingWebSocket from 'reconnecting-websocket';
import { versionConfig } from '@/config';


let navigate:NavigateFunction|undefined;

export const setNavigate = (nav:NavigateFunction) => {
  navigate = nav;
};
let sid = '';
export const setSid = (newSid:string) => {
  sid = newSid;
};
export const getSid = () => {
  return sid;
};

export interface ResponseData<T> {
  data: T;
}
export interface ResponseList<T> {
  TotalCount: number;
  GroupList: T[];
}

export interface ResponseError {
  Error: {
    Code: string;
    Message: string;
  };
}
export interface ResponseIf<T> {
  Response: T;
  retCode?: number;
  Error?: string;
}
export type ResponseInfo<T> = AxiosResponse<ResponseIf<ResponseData<T> | ResponseList<T> | ResponseError> | any, any>;
export type Fetch<P, T> = (params: P) => Promise<T>;

const createChannel = () => {
  return axios.create({
    withCredentials: true,
    baseURL: versionConfig.serverHost, // process.env.NODE_ENV === 'production' ? BASEURL : '/chainmaker',
    headers: {
      withCredentials: true,
      'Content-Type': 'application/x-www-form-urlencoded'
      // 'Access-Control-Allow-Origin': window.location.hostname
    }
  });
};
const requestInterceptor = (config:any) => {
  if (!config.headers) {
    config.headers = {};
  }
  if (!config.data) {
    config.data = {};
  }
  (config.data as any).sid = sid;
  config.data = JSON.stringify(config.data);

  return config;
};
const responseInterceptor = (response:any) => {
  const { data } = response;
  if (data.code !== undefined && data.code !== 0 && data.msg) {
    message.error({
      content: data.msg
    });
  }
  return data;
};
const errorInterceptor = (error:any) => {
  if (error.response.status === 403) {
    message.error({ content: '未登陆' });
    navigate?.('/login');
    return;
  }
  console.log(error);
  Promise.reject(error);
};

const instance = createChannel();
const fileInstance = createChannel();
instance.interceptors.request.use(requestInterceptor);
instance.interceptors.response.use(
  responseInterceptor, errorInterceptor
);
fileInstance.interceptors.response.use(
  responseInterceptor, errorInterceptor
);
// 对错误信息进行默认处理的get请求 封装函数
export const createGetChannel = (url: string): Fetch<any, any> => {
  return (params?: any, transformResponse?: (resp: ResponseInfo<any>) => void) =>
    instance.get(url, {
      params: { ...params },
      transformResponse
    });
};
// 对错误信息进行默认处理的get请求 封装函数
export const createGetChannelBlob = (url: string): Fetch<any, any> => {
  return (params?: any, transformResponse?: (resp: ResponseInfo<any>) => void) =>
    instance.get(url, {
      params: { ...params },
      transformResponse,
      responseType: 'blob'
    });
};

// 对错误信息进行默认处理的post请求 封装函数
export const createPostChannel = (url: string): Fetch<any, any> => {
  return (data?: any) =>
    instance.post(
      url,
      {
        ...data
      }
    );
};
// 对错误信息进行默认处理的post formData请求 封装函数
export const createPostFormDataChannel = (url: string): Fetch<any, any> => {
  return (data?: any) =>
    fileInstance.post(
      url,
      data,
      {
        headers: { 'content-type': 'multipart/form-data' }
      }
    );
};
// 单纯处理的post请求 的封装函数
export const createPostFetch = (url: string): Fetch<any, any> => {
  return (data: any) =>
    axios.post(
      url,
      {
        ...data
      }
    );
};

export const buildWebsocket = (path:string) => {
  const wspath = /^wss?:\/\//.test(path) ? path : `${versionConfig.wsHost}${path}`;
  // document.cookie = `${document.cookie}; domain=${import.meta.env.VITE_WS_HOST.replace(/^wss?:\/\//, '')}`;
  // const wspath = 'ws://local.chainmaker.ide.com:8080/';
  return function(param:any) {
    const keys = Object.keys(param);
    const paramstr = keys.reduce((accumulator, key) => {
      return `${accumulator}&${key}=${param[key]}`;
    }, `sid=${sid}`);
    // console.log(wspath);
    return new ReconnectingWebSocket(`${wspath}?${paramstr}`);
  };
};
